#include "fxcc/core/graph/opengl3/RenderTargetJack.h"
#include "fxcc/core/graph/opengl3/RenderStates.h"

using namespace fxcc::graph::opengl3;

bool RenderTargetJack::Init()
{
    if (m_Desc.m_MipmapData.m_Width <= 0 || m_Desc.m_MipmapData.m_Height <= 0)
    {
        return false;
    }

    int numTextures = m_Desc.m_NumTextures;
    const auto& mipmapLevel = m_Desc.m_MipmapData;

    std::vector<unsigned int> m_Attachments;

    m_FrameBuffer.Bind();

    if (numTextures > 0)
    {
        m_Textures.resize(numTextures);
        m_Attachments.resize(numTextures);

        for (int i = 0; i < numTextures; i++)
        {
            auto texture = std::make_shared<fxcc::graph::opengl3::Texture2DJack>(m_Desc.m_MipmapData);

            int attachment = GL_COLOR_ATTACHMENT0 + i;
            m_Attachments[i] = attachment;

            texture->Bind();
            m_FrameBuffer.BufferTexture2D(attachment, GL_TEXTURE_2D, (unsigned int)texture->GetTextureId());
            
            m_Textures[i] = texture;
        }
        m_FrameBuffer.DrawBuffers(&m_Attachments[0], m_Attachments.size());
    }

    auto attachmentType = m_Desc.m_AttachmentType;

    if (attachmentType == fxcc::graph::common::AttachmentType::_None_)
    {
        ztclog::info("the desc not use an depthstencil attachment");
    }
    else
    {
        auto& rs = fxcc::graph::opengl3::RenderStates::Inst();
        const auto& attachdesc = rs.GetAttachmentDesc(attachmentType);

        fxcc::graph::common::ImageMipmap::MipMapData image = m_Desc.m_MipmapData;
        image.m_NrComponent = 4;
        image.m_HDR = false;

        auto depthStencilTexture  = std::make_shared<fxcc::graph::opengl3::Texture2DJack>(image);

        depthStencilTexture->Bind();
        glTexImage2D(GL_TEXTURE_2D, 0, attachdesc.m_Component, image.m_Width, image.m_Height, 0, attachdesc.m_Format, GL_UNSIGNED_INT_24_8, 0);

        m_FrameBuffer.Bind();
        bool flag = (attachdesc.m_Attachment == GL_DEPTH_STENCIL_ATTACHMENT);

        m_FrameBuffer.BufferTexture2D(attachdesc.m_Attachment, GL_TEXTURE_2D, (unsigned int)depthStencilTexture->GetTextureId());

        m_DepthStencilTexture = depthStencilTexture;
    }

    fxcc::graph::opengl3::FrameBuffer::CheckError();
    fxcc::graph::opengl3::FrameBuffer::UnBind();
    fxcc::graph::opengl3::Texture2DJack::UnBind();

    return true;
}

void fxcc::graph::opengl3::RenderTargetJack::End() const
{
    fxcc::graph::opengl3::FrameBuffer::UnBind();
}

void fxcc::graph::opengl3::RenderTargetJack::ClearColor(const glm::vec4& color)
{
    glClearColor(color.x, color.y, color.z, color.w);
}

void fxcc::graph::opengl3::RenderTargetJack::ClearBuffer(int color, int depthStencil)
{
    int flag{ 0 };
    
    if (color)
    {
        flag |= GL_COLOR_BUFFER_BIT;
    }
    if (depthStencil)
    {
        flag |= (GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
    }

    glClear(flag);
}


void fxcc::graph::opengl3::RenderTargetJack::Begin() const
{
    m_FrameBuffer.Bind();
    Viewport();
    //glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
}

void fxcc::graph::opengl3::RenderTargetJack::Viewport() const
{
    const auto& hd = m_Desc.m_MipmapData;
    glViewport(0, 0, hd.m_Width, hd.m_Height);
}